<template>
    <transition name="fade">
        <div class="image-preview"
            v-show="visible"
            @click="close"
            @mousewheel.prevent="handleWheel"
            @mousemove="onDrag"
            @mouseup="stopDrag"
            @keydown.left="prev"
            @keydown.right="next"
            @touchstart="startTouch"
            @touchmove.prevent="onTouch"
            @touchend="stopTouch"
            tabindex="-1"
            ref="imagePreviewRef">

            <div class="preview-wrapper">
                <img 
                    :src="currentImage" 
                    :style="{ 
                        transform: `translate(${position.x}px, ${position.y}px) scale(${scale}) rotate(${rotation}deg)` 
                    }"
                    @click.stop
                    @mousedown.stop.prevent="startDrag"
                    @touchstart.stop="startTouch"
                >
            </div>

            <div class="nav-buttons" v-if="images.length > 1">
                <button class="nav-btn prev" @click.stop="prev" :disabled="currentIndex <= 0">
                    <i class="fas fa-chevron-left"></i>
                </button>
                <button class="nav-btn next" @click.stop="next" :disabled="currentIndex >= images.length - 1">
                    <i class="fas fa-chevron-right"></i>
                </button>
            </div>

            <div class="preview-toolbar" @click.stop>
                <button class="tool-btn" @click="rotate(-90)">
                    <i class="fas fa-undo"></i>
                </button>
                <button class="tool-btn" @click="rotate(90)">
                    <i class="fas fa-redo"></i>
                </button>
                <button class="tool-btn" @click="zoom(0.1)">
                    <i class="fas fa-search-plus"></i>
                </button>
                <button class="tool-btn" @click="zoom(-0.1)">
                    <i class="fas fa-search-minus"></i>
                </button>
                <button class="tool-btn" @click="reset">
                    <i class="fas fa-sync-alt"></i>
                </button>
                <button class="tool-btn" @click="close">
                    <i class="fas fa-times"></i>
                </button>
            </div>

            <div class="image-counter" v-if="images.length > 1">
                {{ currentIndex + 1 }} / {{ images.length }}
            </div>


        </div>
    </transition>
</template>

<script setup>
import { ref, computed, nextTick, onMounted, onBeforeUnmount, } from 'vue';
const imagePreviewRef = ref(null)

const visible = ref(false)
const images = ref([])
const currentIndex = ref(0)
const scale = ref(1)
const rotation = ref(0)
const position = ref({ x: 0, y: 0 }) 
const isDragging = ref(false) 
const lastMousePosition = ref( { x: 0, y: 0 })
const initialDistance= ref(0) 
const initialScale= ref(1) 

const currentImage = computed(()=>{
    return images.value[currentIndex.value] || ''
})

/**
 * 显示图片预览
 * @param imgs 图片数组
 * @param startIndex 开始显示的索引
 */
 const show = (imgs, startIndex = 0) => {
  images.value = Array.isArray(imgs)? imgs : [imgs];
  currentIndex.value = startIndex;
  visible.value = true;
  reset();
  document.body.style.overflow = 'hidden';
  nextTick(() => {
    if (imagePreviewRef.value) {
      imagePreviewRef.value.focus();
    }
  });
};

const close = () => {
  visible.value = false;
  document.body.style.overflow = '';
};

const prev = () => {
  if (currentIndex.value > 0) {
    currentIndex.value--;
    reset();
  }
};

const next = () => {
  if (currentIndex.value < images.value.length - 1) {
    currentIndex.value++;
    reset();
  }
};

const rotate = (deg) => {
  rotation.value = (rotation.value + deg) % 360; 
  //角度值归一化到 0 到 360 度这个区间内
};

const zoom = (delta) => {
  const newScale = scale.value + delta;
  if (newScale >= 0.1 && newScale <= 3) {
    scale.value = newScale;
  }
};

const reset = () => {
  scale.value = 1;
  rotation.value = 0;
  position.value = { x: 0, y: 0 };
};

const handleWheel = (e) => {
  const delta = e.deltaY > 0? -0.1 : 0.1;
  zoom(delta);
};

const startDrag = (e) => {
  isDragging.value = true;
  lastMousePosition.value = {
    x: e.clientX,
    y: e.clientY
  };
};

const onDrag = (e) => {
  if (!isDragging.value) return;

  const deltaX = e.clientX - lastMousePosition.value.x;
  const deltaY = e.clientY - lastMousePosition.value.y;

  position.value.x += deltaX;
  position.value.y += deltaY;

  lastMousePosition.value = {
    x: e.clientX,
    y: e.clientY
  };
};

const stopDrag = () => {
  isDragging.value = false;
};

const startTouch = (e) => {
  if (e.touches.length === 2) {
    e.preventDefault();
    const touch1 = e.touches[0];
    const touch2 = e.touches[1];
    initialDistance.value = Math.hypot(
      touch2.clientX - touch1.clientX,
      touch2.clientY - touch1.clientY
    );
    initialScale.value = scale.value;
  } else if (e.touches.length === 1 && e.target.tagName.toLowerCase() === 'img') {
    e.preventDefault();
    isDragging.value = true;
    lastMousePosition.value = {
      x: e.touches[0].clientX,
      y: e.touches[0].clientY
    };
  }
};

const onTouch = (e) => {
  if (e.touches.length === 2) {
    const touch1 = e.touches[0];
    const touch2 = e.touches[1];
    const currentDistance = Math.hypot(
      touch2.clientX - touch1.clientX,
      touch2.clientY - touch1.clientY
    );

    const newScale = (currentDistance / initialDistance.value) * initialScale.value;
    if (newScale >= 0.1 && newScale <= 3) {
      scale.value = newScale;
    }
  } else if (isDragging.value && e.touches.length === 1) {
    const deltaX = e.touches[0].clientX - lastMousePosition.value.x;
    const deltaY = e.touches[0].clientY - lastMousePosition.value.y;

    position.value.x += deltaX;
    position.value.y += deltaY;

    lastMousePosition.value = {
      x: e.touches[0].clientX,
      y: e.touches[0].clientY
    };
  }
};

const stopTouch = () => {
  isDragging.value = false;
};

onMounted(() => {
  document.addEventListener('keydown', (e) => {
    if (e.key === 'Escape') {
      close();
    }
  });
});

onBeforeUnmount(() => {
  document.removeEventListener('keydown', (e) => {
    if (e.key === 'Escape') {
      close();
    }
  });
});
</script>

<style lang="scss" scoped>
.image-preview {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.6);
  z-index: 2000;
  display: flex;
  align-items: center;
  justify-content: center;
  
  .preview-wrapper {
    max-width: 90vw;
    max-height: 90vh;
    
    img {
      max-width: 100%;
      max-height: 90vh;
      object-fit: contain;
      cursor: grab;
      user-select: none;
      
      &:active {
        cursor: grabbing;
      }
    }
  }
  
  .preview-toolbar {
    position: fixed;
    bottom: 30px;
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    gap: 10px;
    padding: 10px;
    background: rgba(255, 255, 255, 0.1);
    backdrop-filter: blur(10px);
    border-radius: 8px;
    
    .tool-btn {
      width: 40px;
      height: 40px;
      border: none;
      background: rgba(255, 255, 255, 0.2);
      color: white;
      border-radius: 8px;
      cursor: pointer;
      transition: all 0.2s ease;
      
      &:hover {
        background: rgba(255, 255, 255, 0.3);
        transform: translateY(-2px);
      }
      
      i {
        font-size: 16px;
      }
    }
  }
}

.fade-enter-active {
  animation: fadeIn 0.3s ease;
  
  img {
    animation: zoomIn 0.3s ease;
  }
}

.fade-leave-active {
  animation: fadeOut 0.3s ease;
  
  img {
    animation: zoomOut 0.3s ease;
  }
}

@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes fadeOut {
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}

@keyframes zoomIn {
  from {
    opacity: 0;
    transform: translate(0, 0) scale(0.3) rotate(0deg);
  }
  to {
    opacity: 1;
    transform: translate(0, 0) scale(1) rotate(0deg);
  }
}

@keyframes zoomOut {
  from {
    opacity: 1;
    transform: translate(0, 0) scale(1) rotate(0deg);
  }
  to {
    opacity: 0;
    transform: translate(0, 0) scale(0.3) rotate(0deg);
  }
}

.nav-buttons {
  position: fixed;
  top: 50%;
  left: 0;
  right: 0;
  transform: translateY(-50%);
  display: flex;
  justify-content: space-between;
  padding: 0 20px;
  pointer-events: none;

  .nav-btn {
    width: 44px;
    height: 44px;
    border: none;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.2);
    color: white;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all 0.2s ease;
    pointer-events: auto;
    
    &:hover:not(:disabled) {
      background: rgba(255, 255, 255, 0.3);
      transform: scale(1.1);
    }
    
    &:disabled {
      opacity: 0.5;
      cursor: not-allowed;
    }
    
    i {
      font-size: 20px;
    }
  }
}

.image-counter {
  position: fixed;
  bottom: 100px;
  left: 50%;
  transform: translateX(-50%);
  background: rgba(0, 0, 0, 0.5);
  color: white;
  padding: 6px 12px;
  border-radius: 4px;
  font-size: 14px;
}
</style>